package Game;
import java.io.Serializable;

import javax.swing.JOptionPane;

/**
 * Character.java
 * 
 * This class defines a character object. A character has a name, a profession, 
 * an integer stating how much health a player has, and a Health Status ( dead, tired...)
 * 
 * @author Ray DeCuir
 * @version 1.4 
 *
 */
public class Character implements Serializable{

	private double consumptionLevel;
	
	// The character's name
	private String name;
	
	// An enumerated type representing the players profession
	private CharacterType profession;
	
	// an integer holding the players numeric health
	private int health;
	
	// The player's health status as represented in the HealthStatus enumerated type
	private HealthState healthStatus;
	
	// Represents the character's health status as a sliding scale
	private double healthSlider;
	
	/**
	 * Constructor for the Character, constructs a new character 
	 * object using the parameterized name and profession
	 * 
	 * @param name The name for the character
	 * @param profession The profession for the character
	 */
	public Character( String name, CharacterType profession)
	{
		this.name = name;
		this.profession = profession;
		
		// set the initial health of the character to 100, the maximum
		health = 100;
		
		// set the health state of the character to normal
		healthStatus = HealthState.NORMAL;
		
		// sets the health slider to the normal value
		healthSlider = 4;
		
		consumptionLevel = Ration.getConsumptionLevel() * profession.getConsumptionMulti();
	}
	
	
	/**
	 * setHealth
	 * 
	 * This method sets the health for a particular player. If that player has health over 100,
	 * the health is set to 100. If the health is set to zero or below, the character's health 
	 * is set to 0 and the player's health status is set to dead
	 * 
	 * @param health The new health of the character
	 */
	public void setHealth( int health )
	{
		if ( isAlive() )
		{
			if ( health > 100 )
			{
				this.health = 100;
			}
			else if ( health <= 0)
			{
				this.health = 0;
				healthStatus = HealthState.DEAD;
			}
			else
			{
				this.health = health;
			}
		}
	}
	
	
	/**
	 * getHealth
	 * 
	 * This method returns the character's health
	 * 
	 * @return An integer representing the character's health
	 */
	public int getHealth()
	{
		return health;
	}
	
	
	/**
	 * getHealthStatus
	 * 
	 * This method returns an HealthState enumerated type representing the character's Health State.
	 * 
	 * @return The health status of the character, (DEAD, NORMAL, etc)
	 */
	public HealthState getHealthStatus()
	{
		return healthStatus;
	}
	
	
	/**
	 * getProfession
	 * 
	 * This method returns an enumerated type denoting the character's profession 
	 * 
	 * @return The profession of the character denoted in an enumerated type
	 */
	public CharacterType getProfession()
	{
		return profession;
	}
	
	
	/**
	 * setProfession
	 * 
	 * This method sets the profession of a character to the parameterized type
	 * 
	 * @param profession The new profession for the character
	 */
	public void setProfession ( CharacterType profession)
	{
		this.profession = profession;
	}
	
	
	/**
	 * isAlive
	 * 
	 * This method returns a boolean denoting if a particular character is alive or not ( Health 
	 * Status is not DEAD) 
	 * 
	 * @return A boolean denoting if a particular character is alive, true if alive, false if dead
	 */
	public boolean isAlive()
	{
		return healthStatus != HealthState.DEAD;
	}
	
	
	/**
	 * setHealthStatus
	 * 
	 * This method sets the health status of a particular character to the parameterized value
	 * 
	 * @param healthStatus The new health status for the character
	 */
	public void setHealthStatus( HealthState healthStatus)
	{
		this.healthStatus = healthStatus;
		healthSlider = healthStatus.getIndex();
	}
	
	
	/**
	 * getName
	 * 
	 * This method returns the name of a character
	 * 
	 * @return The name of the character
	 */
	public String getName()
	{
		return name;
	}
	
	
	
	/**
	 * setName
	 * 
	 * This method sets the name of the character to the parameterized name
	 * 
	 * @param name The new name for the character
	 */
	public void setName( String name)
	{
		this.name = name;
	}
	
	
	/**
	 * 
	 * Feeds the character based on the amount of food given as a parameter. Updates the health status and health 
	 * as a function of how much food the character had to eat
	 * 
	 * @param amount The amount of food to feed the character
	 */
	public void feed(int amount)
	{
		if ( isAlive() )
		{
			healthSlider = healthSlider + 0.3 * ( amount - consumptionLevel  );
			int hs = (int)Math.round(healthSlider);
			if ( hs < 0)
				hs = 0;
			else if (hs > 5)
				hs = 5;
			healthStatus = HealthState.values()[hs];
			setHealth( getHealth() + (int)(3 * ( amount - consumptionLevel  )) );
			if( HealthState.values()[hs] == HealthState.DEAD)
			{
				JOptionPane.showMessageDialog(null, name + " has died of starvation");
			}
		}
	}
	
	
	/**
	 * Updates the character's health status and health based on the pace, a grueling pace will reduce both of 
	 * these while a resting pace will increase it
	 * 
	 * @param playerPace
	 */
	public void travelUpdate(Pace playerPace)
	{
		if ( isAlive() )
		{
			healthSlider = healthSlider + 0.3 * ( 1.5 - 2 * playerPace.getMulti()  );
			int hs = (int)Math.round(healthSlider);
			if ( hs < 0)
				hs = 0;
			else if (hs > 5)
				hs = 5;
			healthStatus = HealthState.values()[hs];
			setHealth( getHealth() + (int)(3 * ( 1.5 - 2 * playerPace.getMulti()  )) );
			if( HealthState.values()[hs] == HealthState.DEAD)
			{
				JOptionPane.showMessageDialog(null, name + " has died of pace");
			}
		}
	}
}
